<template>
  <view class="forget-container">
    <view class="title"> 忘记密码 </view>
    <view class="content">
      <!-- 登录表单开始 -->
      <view class="form">
        <view class="form-item">
          <uni-easyinput type="number" v-model="mobile" :trim="true" prefixIcon="phone-filled" maxlength="11" placeholder="请输入手机号" @input="setErrorEmpty('mobile')"></uni-easyinput>
          <view class="error-text" v-if="mobileError">
            {{ mobileError }}
          </view>
        </view>
        <view class="form-item">
          <view class="captcha-pic">
            <uni-easyinput type="number" v-model="captchaCode" :trim="true" prefixIcon="medal-filled" maxlength="6" placeholder="请输入图片验证码答案" @input="setErrorEmpty('captchaCode')"></uni-easyinput>
            <view class="pic" @click="freshCaptcha">
              <img v-if="captchaUrl" class="captcha-pic" :src="captchaUrl" title="点击刷新" />
              <view class="error" v-else> 点击刷新 </view>
            </view>
          </view>
          <view class="error-text" v-if="captchaCodeError">
            {{ captchaCodeError }}
          </view>
        </view>

        <view class="form-item">
          <view class="code-content">
            <uni-easyinput type="number" v-model="code" :trim="true" prefixIcon="email-filled" maxlength="6" placeholder="请输入验证码" @input="setErrorEmpty('code')"></uni-easyinput>
            <view class="get-code" @click="getVerifyCode"> {{ codeText }} </view>
          </view>

          <view class="error-text" v-if="codeTextError">
            {{ codeTextError }}
          </view>
        </view>

        <view class="form-item">
          <uni-easyinput type="password" :trim="true" prefixIcon="locked-filled" v-model="password" maxlength="16" placeholder="请输入密码" @input="setErrorEmpty('oldPassword')"></uni-easyinput>
          <view class="error-text" v-if="passwordError">
            {{ passwordError }}
          </view>
        </view>
        <view class="form-item">
          <uni-easyinput type="password" :trim="true" prefixIcon="locked-filled" v-model="confirmPassword" maxlength="16" placeholder="请再次确认密码" @input="setErrorEmpty('confirmPassword')"></uni-easyinput>
          <view class="error-text" v-if="confirmPasswordError">
            {{ confirmPasswordError }}
          </view>
        </view>
      </view>
      <!-- 登录表单结束 -->

      <!-- 登录开始 -->
      <view class="login">
        <button class="btn" type="primary" @click="forget">确定</button>
      </view>
      <!-- 登录结束 -->
      <Transition name="toast">
        <Toast v-if="globalLoading"></Toast>
      </Transition>
    </view>
  </view>
</template>

<script lang="ts">
import Vue from 'vue'
import { mapState } from 'vuex'
import { encrypt_password } from '@/utils/aesEncode'
import { UserTypes } from '@/store/actions_types/actions_types'
import { forgetPassword, getCaptchaImageCode, getVerify, refreshCaptchaImages } from '@/api'

type DateType = {
  mobile: string
  code: string
  password: string
  captchaCode: string
  confirmPassword: string
  mobileError: string
  codeTextError: string
  captchaCodeError: string
  passwordError: string
  confirmPasswordError: string
  hashkey: string
  captchaUrl: string
  codeText: string
  time: number
  timer: null | number
}

type ValType = 'mobile' | 'captchaCode' | 'code' | 'oldPassword' | 'confirmPassword'

export default Vue.extend({
  data(): DateType {
    return {
      mobile: '',
      code: '',
      password: '',
      captchaCode: '',
      confirmPassword: '',
      mobileError: '',
      codeTextError: '',
      captchaCodeError: '',
      passwordError: '',
      confirmPasswordError: '',
      hashkey: '',
      captchaUrl: '',
      codeText: '获取验证码',
      time: 60,
      timer: null
    }
  },
  computed: {
    ...mapState('user', ['globalLoading'])
  },
  onLoad() {
    this.getCaptcha()
  },
  methods: {
    async forget() {
      // 验证手机号和登录密码是否正确
      if (!this.mobile) {
        return (this.mobileError = '请输入手机号')
      }
      if (!/^1[3-9]\d{9}$/.test(this.mobile)) {
        return (this.mobileError = '手机号格式错误')
      }
      // 图片验证码必填
      if (!this.captchaCode) {
        return (this.captchaCodeError = '请输入图片验证码')
      }
      // 短信验证码必填
      if (!this.code) {
        return (this.codeTextError = '请输入短信验证码')
      }
      if (!/^\d{6}$/.test(this.code)) {
        return (this.codeTextError = '短信验证码格式错误')
      }
      // 验证密码
      if (!this.password) {
        return (this.passwordError = '请输入密码')
      }
      if (!/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$/.test(this.password)) {
        return (this.passwordError = '密码为数字字母组合,长度为6-16位')
      }
      // 再次验证密码
      if (!this.confirmPassword) {
        return (this.confirmPasswordError = '请再次输入密码')
      }
      if (!/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$/.test(this.confirmPassword)) {
        return (this.confirmPasswordError = '密码为数字字母组合,长度为6-16位')
      }
      if (this.confirmPassword !== this.password) {
        return (this.confirmPasswordError = '两次输入的密码不一致')
      }
      // 对密码进行aes加密
      const aes_password = encrypt_password(this.password, this.mobile)

      this.$store.commit(`user/${UserTypes.SET_LOADING}`, true)
      // 发起请求进行登录
      try {
        const payload = {
          mobile: this.mobile,
          captcha_code: this.captchaCode,
          code: this.code,
          hashkey: this.hashkey,
          password: aes_password,
          confirm_password: aes_password
        }
        const data = await forgetPassword(payload)
        if (data.code === 0) {
          this.setErrorTip('密码重置成功', 'success')
          setTimeout(() => {
            // 两秒钟之后返回登录页面
            uni.navigateBack()
          }, 2000)
        } else {
          this.setErrorTip(data.message)
        }
      } catch {
        this.setErrorTip('重置失败<br>请检查网络')
      }
    },
    // 获取图片验证码
    async getCaptcha() {
      try {
        // 展示获取动画
        this.$store.commit(`user/${UserTypes.SET_LOADING}`, true)
        const data = await getCaptchaImageCode()
        if (data.code === 0) {
          this.captchaUrl = `${process.env.VUE_APP_BASE_BUILD}${data.data.image_url}`
          this.hashkey = data.data.hashkey
          this.$store.commit(`user/${UserTypes.SET_LOADING}`, false)
        } else {
          this.setErrorTip(data.message)
        }
      } catch {
        this.setErrorTip('获取失败<br>请检查网络')
      }
    },
    // 刷新验证码
    async freshCaptcha() {
      try {
        // 展示获取动画
        this.setErrorTip('正在刷新...', 'loading')
        const data = await refreshCaptchaImages({ hashkey: this.hashkey })
        if (data.code === 0) {
          this.captchaUrl = `${process.env.VUE_APP_BASE_BUILD}${data.data.image_url}`
          this.hashkey = data.data.hashkey
          this.$store.commit(`user/${UserTypes.SET_LOADING}`, false)
        } else {
          this.setErrorTip(data.message)
        }
      } catch {
        this.setErrorTip('验证码刷新失败<br>请检查网络')
      }
    },
    // 获取短信验证码
    async getVerifyCode() {
      if (this.codeText !== '获取验证码') return
      if (!this.mobile) {
        return (this.mobileError = '请输入手机号')
      }
      if (!/^1[3-9]\d{9}$/.test(this.mobile)) {
        return (this.mobileError = '手机号格式错误')
      }
      if (!this.captchaCode) {
        return (this.captchaCodeError = '请输入验证码答案')
      }
      try {
        this.$store.commit(`user/${UserTypes.SET_LOADING}`, true)
        const data = await getVerify({ mobile: this.mobile, hashkey: this.hashkey, captcha: this.captchaCode })
        if (data.code === 0) {
          this.setErrorTip(data.message, 'success')
          // 开启定时器
          this.codeText = `${this.time}s后重试`
          this.timer = setInterval(() => {
            this.codeText = `${this.time}s后重试`
            this.time--
            if (this.time <= 0) {
              this.time = 60
              this.codeText = '获取验证码'
              if (this.timer) {
                clearInterval(this.timer)
              }
            }
          }, 1000)
        } else {
          this.setErrorTip(data.message)
        }
      } catch {
        this.setErrorTip('获取失败，请检查网络')
      }
    },
    // 设置错误提示
    setErrorTip(message: string, loading_type: 'waring' | 'loading' | 'success' = 'waring') {
      this.$store.commit(`user/${UserTypes.SET_LOADING_TYPE}`, loading_type)
      this.$store.commit(`user/${UserTypes.SET_MESSAGE}`, message)
      this.$store.commit(`user/${UserTypes.SET_LOADING}`, true)
    },
    // 将错误信息置空
    setErrorEmpty(val: ValType) {
      switch (val) {
        case 'mobile':
          return (this.mobileError = '')
        case 'captchaCode':
          return (this.captchaCodeError = '')
        case 'code':
          return (this.codeTextError = '')
        case 'oldPassword':
          return (this.passwordError = '')
        case 'confirmPassword':
          return (this.confirmPasswordError = '')
        default:
          return
      }
    }
  }
})
</script>

<style lang="scss" scoped>
.forget-container {
  height: 100vh;
  font-family: 'aliregular';
  background: linear-gradient(to bottom, rgba(26, 82, 118, 0.2), rgba(26, 82, 118, 0.4), rgba(26, 82, 118, 0.6), rgba(26, 82, 118, 0.8), rgba(26, 82, 118, 1));
  color: #fff;

  .title {
    padding: 120rpx 80rpx 30rpx;
    font-size: 60rpx;
    font-weight: 600;
    color: $uni-theme-color;
  }

  .content {
    padding: 0 60rpx 60rpx;
    .form {
      .form-item {
        margin-bottom: 20rpx;

        .captcha-pic,
        .code-content {
          display: flex;
          align-items: center;

          .pic {
            width: 200rpx;
            height: 70rpx;
            border-radius: 0 999rpx 999rpx 0;
            overflow: hidden;
            border: 2rpx solid $uni-theme-color;
            border-left-color: #fff;
            display: flex;
            align-items: center;
            justify-content: center;
            background-color: $uni-theme-color;

            .error {
              font-size: 28rpx;
            }

            .captcha-pic {
              width: 100%;
              height: 100%;
            }
          }

          .get-code {
            margin: 0;
            color: #fff;
            font-size: 28rpx;
            text-align: center;
            line-height: 70rpx;
            width: 200rpx;
            border-radius: 0 999rpx 999rpx 0;
            border: 2rpx solid $uni-theme-color;
            padding: 0 20rpx;
            border-left-color: #fff;
            background-color: $uni-theme-color;
          }
        }

        .error-text {
          color: red;
          font-size: 24rpx;
          margin-top: 10rpx;
          margin-left: 20rpx;
        }

        ::v-deep .uni-easyinput__content {
          background-color: $uni-theme-color !important;
          color: #fff;
          caret-color: #fff;
        }

        ::v-deep .is-input-border {
          border-radius: 999rpx;
          border-color: $uni-theme-color !important;
        }

        ::v-deep .is-focused {
          border-color: #fff !important;
        }

        &.form-item:nth-of-type(3),
        &.form-item:nth-of-type(2) {
          ::v-deep .is-input-border {
            border-right-width: 0;
            border-radius: 999rpx 0 0 999rpx !important;
          }
        }

        ::v-deep .uni-icons {
          color: #c0c4cc !important;
        }
      }
    }

    .login {
      margin-top: 120rpx;
      .btn {
        background-color: $uni-theme-color;
        color: #fff;
        border-radius: 999rpx;
        font-size: 30rpx;
        font-weight: 700;
      }
    }
  }
}
</style>
